package model.gfs;

import java.io.ByteArrayInputStream;
import java.text.Format;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import main.gfs.Loader;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;

/**
 * Это класс одного тикета. просто банальный список полей тикета и геттеров с
 * сеттареми для них
 * 
 * @author Cobalt
 * @since 20120129
 */
public class Ticket implements Parcelable {
	private int Id, Uid, Pid;
	private String Ptitle, Title, Txt, Type, UserName;
	public boolean IsAvatar;
	private Date Date;

	public Ticket() {
		Id = Uid = Pid = 0;
		Ptitle = Title = Txt = Type = UserName = "";
		IsAvatar = false;
		Date = new Date();
	}

	public int getId() {
		return Id;
	}

	public void setId(int id) {
		Id = id;
	}

	public int getUid() {
		return Uid;
	}

	public void setUid(int uid) {
		Uid = uid;
	}

	public int getPid() {
		return Pid;
	}

	public void setPid(int pid) {
		Pid = pid;
	}

	public String getPtitle() {
		return Ptitle;
	}

	public void setPtitle(String ptitle) {
		Ptitle = ptitle;
	}

	public String getTitle() {
		if (Title.equals("") && (!Ptitle.equals("") || Ptitle != null))
			Title = "RE: " + Ptitle;
		return Title;
	}

	public void setTitle(String title) {
		Title = title;
	}

	public String getTxt() {
		return Txt;
	}

	public void setTxt(String txt) {
		Txt = txt;
	}

	public String getType() {
		return Type;
	}

	public void setType(String type) {
		Type = type;
	}

	public String getUserName() {
		return UserName;
	}

	public void setUserName(String userName) {
		UserName = userName;
	}

	public Date getDate() {
		return Date;
	}

	public void setDate(Date date) {
		Date = date;
	}

	public boolean equals(Object obj) {
		if (obj == this)
			return true;

		/* obj ссылается на null */
		if (obj == null)
			return false;

		/* Удостоверимся, что ссылки имеют тот же самый тип */
		if (!(getClass() == obj.getClass()))
			return false;
		else {
			Ticket tmp = (Ticket) obj;
			if (tmp.Id == this.Id && tmp.getType().equals(Type))
				return true;
			else
				return false;
		}
	}

	/**
	 * функция парсит xml бок ticket
	 * 
	 */
	public void parseXML(Node xml) {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		formatter.setTimeZone(TimeZone.getTimeZone("Europe/Moscow"));
		NodeList ticket = xml.getChildNodes();
		for (int j = 0; j < ticket.getLength(); j++) {
			if (ticket.item(j).getNodeName().equals("id")) {
				setId(Integer.parseInt(ticket.item(j).getFirstChild()
						.getNodeValue()));
			}
			if (ticket.item(j).getNodeName().equals("uid")) {
				setUid(Integer.parseInt(ticket.item(j).getFirstChild()
						.getNodeValue()));
			}
			if (ticket.item(j).getNodeName().equals("pid")) {
				if (ticket.item(j).getChildNodes().getLength() > 0)
					setPid(Integer.parseInt(ticket.item(j).getFirstChild()
							.getNodeValue()));
			}
			if (ticket.item(j).getNodeName().equals("ptitle")) {
				if (ticket.item(j).getChildNodes().getLength() > 0)
					setPtitle(ticket.item(j).getFirstChild().getNodeValue());
			}
			if (ticket.item(j).getNodeName().equals("title")) {
				if (ticket.item(j).getChildNodes().getLength() > 0)
					setTitle(ticket.item(j).getFirstChild().getNodeValue());
			}
			if (ticket.item(j).getNodeName().equals("txt")) {
				if (ticket.item(j).getChildNodes().getLength() > 0)
					setTxt(ticket.item(j).getFirstChild().getNodeValue());
			}
			if (ticket.item(j).getNodeName().equals("type")) {
				setType(ticket.item(j).getFirstChild().getNodeValue());
			}
			if (ticket.item(j).getNodeName().equals("username")) {
				setUserName(ticket.item(j).getFirstChild().getNodeValue());
			}
			if (ticket.item(j).getNodeName().equals("avatars")) {
				if (ticket.item(j).getFirstChild().getNodeValue().equals("Y"))
					IsAvatar = true;
				else
					IsAvatar = false;
			}
			if (ticket.item(j).getNodeName().equals("date")) {
				try {
					setDate(formatter.parse(ticket.item(j).getFirstChild()
							.getNodeValue()));
				} catch (Exception e) {
					Log.e("time", e.getMessage());
				}
			}

		}
	}

	/**
	 * функция отправки тикета на сервер
	 * 
	 * @return boolean удалось отправить или нент
	 */
	public boolean sendToServer(Activity context) {
		Format formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Document doc = null;
		DocumentBuilder builder;
		try {
			builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		} catch (ParserConfigurationException e) {
			Log.e("xml", e.getMessage());
			return false;
		}
		doc = builder.newDocument();
		// заполняем xml
		Element root = doc.createElement("ticket");
		Element el = doc.createElement("id");
		el.appendChild(doc.createTextNode("" + Id));
		root.appendChild(el);
		el = doc.createElement("uid");
		el.appendChild(doc.createTextNode("" + Uid));
		root.appendChild(el);
		el = doc.createElement("pid");
		el.appendChild(doc.createTextNode("" + Pid));
		root.appendChild(el);
		el = doc.createElement("ptitle");
		el.appendChild(doc.createCDATASection(Ptitle));
		root.appendChild(el);
		el = doc.createElement("title");
		el.appendChild(doc.createCDATASection(Title));
		root.appendChild(el);
		el = doc.createElement("type");
		el.appendChild(doc.createTextNode(Type));
		root.appendChild(el);
		el = doc.createElement("txt");
		el.appendChild(doc.createCDATASection(Txt));
		root.appendChild(el);
		el = doc.createElement("username");
		el.appendChild(doc.createCDATASection(UserName));
		root.appendChild(el);
		el = doc.createElement("avatars");
		el.appendChild(doc.createTextNode(IsAvatar ? "Y" : "N"));
		root.appendChild(el);
		el = doc.createElement("date");
		el.appendChild(doc.createTextNode(formatter.format(Date)));
		root.appendChild(el);
		doc.appendChild(root);

		// преобразуем в строку
		String xml = "";
		try {
			DOMSource domSource = new DOMSource(doc);
			TransformerFactory tf = TransformerFactory.newInstance();
			Transformer transformer = tf.newTransformer();
			// transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
			// "yes");
			transformer.setOutputProperty(OutputKeys.METHOD, "xml");
			transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
			transformer.setOutputProperty(
					"{http://xml.apache.org/xslt}indent-amount", "4");
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			java.io.StringWriter sw = new java.io.StringWriter();
			StreamResult sr = new StreamResult(sw);
			transformer.transform(domSource, sr);
			xml = sw.toString();
		} catch (Exception e) {
			Log.e("xml", e.getMessage());
			return false;
		}

		// прочтем из конфига логин и пароль
		SharedPreferences settings = context.getSharedPreferences("ACCOUNT", 0);
		String username = settings.getString("username", null);
		String password = settings.getString("password", null);

		String res = "";
		try {
			res = Loader.PostHttpsUrl("https://www.gfs-team.ru/xml.php?login="
					+ username + "&password=" + password, "ticket=" + xml);
		} catch (Exception e) {
			Log.e("send", e.getMessage());
			return false;
		}

		Log.i("send", res);

		// теперь надо распарсить полученную XML-ку
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			factory.setNamespaceAware(true);
			DocumentBuilder bulder = factory.newDocumentBuilder();
			doc = bulder.parse(new ByteArrayInputStream(res.getBytes()));
		} catch (Exception e) {
			Log.e("answ", e.getMessage());
			return false;
		}
		Node rootnode = doc.getFirstChild();
		NodeList nodes = rootnode.getChildNodes();
		if (nodes.getLength() > 0) {
			// если в ответ имеет типа ошибки
			if (nodes.item(0).getNodeName().equals("error")) {
				NamedNodeMap attributes = nodes.item(0).getAttributes();
				Node nameAttrib = attributes.getNamedItem("id");
				int id = Integer.parseInt(nameAttrib.getNodeValue());
				switch (id) {
				case 1:
					// ошибка авторизации
					Log.e("auth", nodes.item(0).getFirstChild().getNodeValue());
					return false;
				default:
					// какая-то другая ошибко
					Log.e("send", nodes.item(0).getFirstChild().getNodeValue());
					return false;
				}
			}
		} else {
			Log.e("send", "короткий ответ");
			return false;
		}
		return true;
	}

	/**
	 * два метода и класс наследуемых от родителя они нужны для серриализации
	 * объекта которая нужна в свою очередь для возможности передачи объекта
	 * между активити
	 * 
	 */
	public int describeContents() {
		return 0;
	}

	public static final Parcelable.Creator<Ticket> CREATOR = new Parcelable.Creator<Ticket>() {

		public Ticket createFromParcel(Parcel in) {
			SimpleDateFormat formatter = new SimpleDateFormat(
					"yyyy-MM-dd HH:mm:ss");
			formatter.setTimeZone(TimeZone.getTimeZone("Europe/Moscow"));
			Ticket t = new Ticket();
			t.setId(in.readInt());
			t.setUid(in.readInt());
			t.setPid(in.readInt());
			t.setPtitle(in.readString());
			t.setTitle(in.readString());
			t.setTxt(in.readString());
			t.setType(in.readString());
			t.setUserName(in.readString());
			t.IsAvatar = (in.readInt() == 1 ? true : false);
			try {
				t.setDate(formatter.parse(in.readString()));
			} catch (ParseException e) {
				t.setDate(new Date());
			}
			return t;
		}

		public Ticket[] newArray(int size) {
			return new Ticket[size];
		}
	};

	public void writeToParcel(Parcel parcel, int i) {
		Format formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		parcel.writeInt(Id);
		parcel.writeInt(Uid);
		parcel.writeInt(Pid);
		parcel.writeString(Ptitle);
		parcel.writeString(Title);
		parcel.writeString(Txt);
		parcel.writeString(Type);
		parcel.writeString(UserName);
		parcel.writeInt(IsAvatar ? 1 : 0);
		parcel.writeString(formatter.format(Date));
	}

}
